using System.Text.Json;
using Audit.Core;
using Audit.EntityFramework;
using Audit.EntityFramework.Core.Samples.Data;
using Audit.EntityFramework.Core.Samples.Extensions;
using Audit.EntityFramework.Core.Samples.Infrastructure.CurrentUser;
using Audit.EntityFramework.Core.Samples.Models;
using Microsoft.EntityFrameworkCore;

var builder = WebApplication.CreateBuilder(args);
builder.Services.AddControllers();
builder.Services.AddSwaggerGen();
builder.Services.AddHttpContextAccessor();
builder.Services.AddTransient<ICurrentUser, CurrentUserContext>();
builder.Services.AddDbContext<ApplicationDbContext>(options =>
    options.UseSqlite("Data Source=database.db"));

#region Audit.EntityFramework.Core Configuration
Audit.Core.Configuration.Setup()
            .UseEntityFramework(config => config.AuditTypeMapper(_ => typeof(AuditLogEntry))
                .AuditEntityAction<AuditLogEntry>((ev, entry, auditEntry) =>
                {
                    auditEntry.Id = Guid.NewGuid();
                    auditEntry.AuditDate = DateTime.UtcNow;
                    auditEntry.Action = entry.Action;
                    auditEntry.TableName = entry.Table;
                    auditEntry.Schema = entry.Schema;
                    auditEntry.UserId = ev.CustomFields.GetUserIdFromCustomFields();
                    auditEntry.PrimaryKey = JsonSerializer.Serialize(entry.PrimaryKey);
                    var oldValues = new Dictionary<string, object>();
                    var newValues = new Dictionary<string, object>();
                    var affectedColumns = new List<string>();
                    
                    // 根据 Changes和State判断是否为新增操作
                    if ((entry.Changes == null || entry.Changes.Count == 0 )&& entry.GetEntry().State == EntityState.Unchanged)
                    {
                        if (entry.ColumnValues != null && entry.ColumnValues.Any())
                        {
                            // 可能是新增操作（只有新值，没有变更）
                            if (entry.ColumnValues != null)
                            {
                                foreach (KeyValuePair<string, object> prop in entry.ColumnValues)
                                {
                                    newValues[prop.Key] = prop.Value;
                                    affectedColumns.Add(prop.Key);
                                }
                            }
                            auditEntry.OldValues = string.Empty;
                            auditEntry.NewValues = JsonSerializer.Serialize(newValues);
                            auditEntry.AffectedColumns = JsonSerializer.Serialize(affectedColumns);
                        }
                    }
                    else
                    {
                        // 删除操作
                        if (entry.GetEntry().State == EntityState.Detached)
                        {
                            foreach (KeyValuePair<string, object> prop in entry.ColumnValues)
                            {
                                oldValues[prop.Key] = prop.Value;
                                affectedColumns.Add(prop.Key);
                            }
                            auditEntry.OldValues = JsonSerializer.Serialize(oldValues);
                            auditEntry.NewValues = string.Empty;
                            auditEntry.AffectedColumns = JsonSerializer.Serialize(affectedColumns);
                        }
                        // 更新操作
                        else
                        {
                            if (entry.Changes != null && entry.Changes.Count > 0)
                            {
                                foreach (EventEntryChange? change in entry.Changes)
                                {
                                    oldValues[change.ColumnName] = change.OriginalValue;
                                    newValues[change.ColumnName] = change.NewValue;
                                    affectedColumns.Add(change.ColumnName);
                                }
                            }
                            auditEntry.OldValues = JsonSerializer.Serialize(oldValues);
                            auditEntry.NewValues = JsonSerializer.Serialize(newValues);
                            auditEntry.AffectedColumns = JsonSerializer.Serialize(affectedColumns);
                        }
                    }
                }));
 #endregion
var app = builder.Build();
if (app.Environment.IsDevelopment())
{
    app.UseSwagger();
    app.UseSwaggerUI();
}
app.MapControllers();
app.UseHttpsRedirection();
app.Run();
